package feizhou.untils.tools;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.Result;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Hashtable;
import java.util.Map;

/**
 * 二维码生成工具类
 *
 * @author <a href="920786312@qq.com">周飞</a>
 * @since 2023/9/19 10:28
 */
public class QrCodeUtil {
    static Logger logger = LoggerFactory.getLogger(QrCodeUtil.class);

    /**
     * 生成二维码图片的base64字符串
     *
     * @param url    url 网址
     * @param width  二维码宽度
     * @param height 二维码高度
     */
    public static String encode(String url, int width, int height) {

        //设置QR二维码参数信息
        Map<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();

        // 指定纠错等级(H为最高级别)
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);


        hints.put(EncodeHintType.CHARACTER_SET, "UTF8"); // 指定编码格式
        hints.put(EncodeHintType.MARGIN, 0);// 白边

        try {
            //MultiFormatWriter 继承Writer
            BitMatrix bitMatrix = new MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, width, height, hints);

            //输出流
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            MatrixToImageWriter.writeToStream(bitMatrix, "png", outputStream);

            String imageToBase64Str = Base64Util.imageToBase64Str(outputStream.toByteArray());
            return imageToBase64Str;
        } catch (Exception e) {
            logger.error("生成的二维码失败");
            e.printStackTrace();
        }
        return null;

    }

    /**
     * 生成二维码
     * David
     *
     * @param url     url 网址
     * @param width   二维码宽度
     * @param height  二维码高度
     * @param imgPath 生成的二维码的保存路径
     */
    public static void encode(String url, int width, int height, String imgPath) {

        //设置QR二维码参数信息
        Map<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();

        // 指定纠错等级(H为最高级别)
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);


        hints.put(EncodeHintType.CHARACTER_SET, "UTF8"); // 指定编码格式
        hints.put(EncodeHintType.MARGIN, 0);// 白边

        try {
            //MultiFormatWriter 继承Writer
            BitMatrix bitMatrix = new MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, width, height, hints);
            //将流保存为图片
            MatrixToImageWriter.writeToStream(bitMatrix, "png", new FileOutputStream(imgPath));
            //MatrixToImageWriter.writeToStream(bitMatrix, "png", response.getOutputStream());// 直接输出图像
        } catch (Exception e) {
            logger.error("生成的二维码失败");
            e.printStackTrace();

        }

    }

    /**
     * 二维码解析
     *
     * @param imgPath 二维码图片路径
     * @return 解析后的二维码内容
     */

    public static String decode(String imgPath) {

        BufferedImage image = null;

        Result result = null;

        try {

            image = ImageIO.read(new File(imgPath));

            LuminanceSource source = new BufferedImageLuminanceSource(image);

            BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));

            Map<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();

            hints.put(DecodeHintType.CHARACTER_SET, "UTF8");

            result = new MultiFormatReader().decode(bitmap, hints);

            return result.getText();

        } catch (Exception e) {
            logger.error("解析二维码失败");
            e.printStackTrace();

        }

        return null;

    }

    // 测试代码
    public static void main(String[] args) {

        String encode = QrCodeUtil.encode("http://www.521show.com/love/7/", 500, 500);
        System.out.println(encode);
//        System.out.println(QrCodeUtil.decode("C:\\Users\\26372\\Desktop\\temp\\1.png"));

    }

}
